package cn.zwt.wolf.util;

import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

/**
 * Created by allen on 7/29/15.
 * 用于多条件动态查询
 *
 */
@Component
public class SearchUtil{

    @PersistenceContext(unitName = "wolf")
    @Qualifier(value = "entityManagerFactory")
    private EntityManager entityManager;

    /**
     * 查询单个结果
     *
     * @param hql
     * @return
     */
    public Object getSingleResult(String hql) throws JPQLSearchException {
        if (hql == null || hql.isEmpty())
            throw new NoHqlException();

        Query query = this.entityManager.createQuery(hql);
        return query.getSingleResult();
    }
    
    
    /**
     * 根据条件查询返回单个结果
     * @param hql
     * @param parameters
     * @return
     * @throws JPQLSearchException
     */
    public Object getSingleResult(String hql,Map<String, Object> parameters) throws JPQLSearchException {
        if (hql == null || hql.isEmpty())
            throw new NoHqlException();
        Query query = this.entityManager.createQuery(hql);
        for (String key : parameters.keySet()) {
            query.setParameter(key, parameters.get(key));
        }
        return query.getSingleResult();
    }


    
    /**
     * 利用源生的sql进行查询
     * @param sql
     * @return
     */
    public  List getNativeQuery(String sql,Class T){
    	Query query = this.entityManager.createNativeQuery(sql,T);
    	List<T> list = query.getResultList();
    	return list;
    }
    
    /**
     * 条件查询
     *
     * @param hql
     * @return
     */
    public List getResultList(String hql) throws JPQLSearchException {
        if (hql == null || hql.isEmpty())
            throw new NoHqlException();

        Query query = this.entityManager.createQuery(hql);
        return query.getResultList();
    }


    /**
     * 条件查询，带序号参数，例如
     * <p/>
     * select s from Series s where name = ?1 and type = ?2
     *
     * @param hql
     * @param parameters
     * @return
     */
    public List getResultList(String hql, List<Object> parameters) throws JPQLSearchException {
        if (hql == null || hql.isEmpty())
            throw new NoHqlException();

        Query query = this.entityManager.createQuery(hql);
        for (int i = 0; i < parameters.size(); i++) {
            query.setParameter(i + 1, parameters.get(i));
        }
        return query.getResultList();
    }

    /**
     * 条件查询，带字符串参数，例如
     * <p/>
     * select s from Series s where name = ：name and type = :type
     *
     * @param hql
     * @param parameters
     * @return
     */
    public List getResultList(String hql, Map<String, Object> parameters) throws JPQLSearchException {
        if (hql == null || hql.isEmpty())
            throw new NoHqlException();

        Query query = this.entityManager.createQuery(hql);
        for (String key : parameters.keySet()) {
            query.setParameter(key, parameters.get(key));
        }
        return query.getResultList();
    }


    /**
     * 条件查询，支持分页
     *
     * @param hql
     * @param pageable
     * @return
     */
    public Page getResultPage(String hql, Pageable pageable) throws JPQLSearchException {
        long total = this.getCount(hql);

        Query query = this.createQuery(hql, pageable);
        List content = query.getResultList();
        return new PageImpl(content, pageable, total);
    }

    /**
     * 条件查询，带序号参数，支持分页
     * <p/>
     * select s from Series s where name = ?1 and type = ?2
     *
     * @param hql
     * @param parameters
     * @param pageable
     * @return
     */
    public Page getResultPage(String hql, List<Object> parameters, Pageable pageable) throws JPQLSearchException {
        long total = this.getCount(hql, parameters);

        Query query = this.createQuery(hql, pageable);
        for (int i = 0; i < parameters.size(); i++) {
            query.setParameter(i + 1, parameters.get(i));
        }
        List content = query.getResultList();
        return new PageImpl(content, pageable, total);
    }

    /**
     * 条件查询，带字符串参数，例如
     * <p/>
     * select s from Series s where name = ：name and type = :type
     *
     * @param hql
     * @param parameters
     * @param pageable
     * @return
     */
    public Page getResultPage(String hql, Map<String, Object> parameters, Pageable pageable) throws JPQLSearchException {
        long total = this.getCount(hql, parameters);

        Query query = this.createQuery(hql, pageable);
        for (String key : parameters.keySet()) {
            query.setParameter(key, parameters.get(key));
        }
        List content = query.getResultList();
        return new PageImpl(content, pageable, total);
    }

    /**
     * 查询满足条件的数量
     *
     * @param hql
     * @return
     */
    private long getCount(String hql) {
        Query query = this.entityManager.createQuery(this.countHql(hql));
        return (Long) query.getSingleResult();
    }

    /**
     * 查询满足条件的数量
     *
     * @param hql
     * @param parameters
     * @return
     */
    private long getCount(String hql, List<Object> parameters) {
        Query query = this.entityManager.createQuery(this.countHql(hql));
        for (int i = 0; i < parameters.size(); i++) {
            query.setParameter(i + 1, parameters.get(i));
        }
        return (Long) query.getSingleResult();
    }

    /**
     * 查询满足条件的数量
     *
     * @param hql
     * @param parameters
     * @return
     */
    public long getCount(String hql, Map<String, Object> parameters) {
        Query query = this.entityManager.createQuery(this.countHql(hql));
        for (String key : parameters.keySet()) {
            query.setParameter(key, parameters.get(key));
        }
        return (Long) query.getSingleResult();
    }

    /**
     * select count 的hql
     *
     * @param hql
     * @return
     */
    public String countHql(String hql) {
        if (hql.trim().toLowerCase().startsWith("from")) {
            return "select count(1) " + hql;
        } else {
            int fromIndex = hql.toLowerCase().indexOf("from");
            return "select count(1) " + hql.substring(fromIndex);
        }
    }


    public Query createQuery(String hql, Pageable pageable) throws JPQLSearchException {
        if (hql == null || hql.isEmpty())
            throw new NoHqlException();
        if (pageable == null)
            throw new NoPageableException();

        int pageSize = pageable.getPageSize();
        int currentPage = pageable.getPageNumber();
        int index = currentPage * pageSize;
        Query query = this.entityManager.createQuery(hql);
        query.setMaxResults(pageSize);
        query.setFirstResult(index);
        return query;
    }

    /**
     * 查询条件非空
     *
     * @param value
     * @return
     */
    public static boolean isNotEmpty(String value) {
        return value != null && !value.trim().isEmpty();
    }

    public static boolean isNotEmpty(int value) {
        return value != 0;
    }


    /**
     * 支持源生的sql
     * @param sql
     * @return
     */
	public List<String> getNativeQuery(String sql) {
		Query query = this.entityManager.createNativeQuery(sql);
    	List list = query.getResultList();
    	return list;
	}
}
